/**
 * Software License, Version 1.0
 * 
 * Copyright 2003 The Trustees of Indiana University.  All rights reserved.
 * 
 *
 *Redistribution and use in source and binary forms, with or without 
 *modification, are permitted provided that the following conditions are met:
 *
 *1) All redistributions of source code must retain the above copyright notice,
 * the list of authors in the original source code, this list of conditions and
 * the disclaimer listed in this license;
 *2) All redistributions in binary form must reproduce the above copyright 
 * notice, this list of conditions and the disclaimer listed in this license in
 * the documentation and/or other materials provided with the distribution;
 *3) Any documentation included with all redistributions must include the 
 * following acknowledgement:
 *
 *"This product includes software developed by the Community Grids Lab. For 
 * further information contact the Community Grids Lab at 
 * http://communitygrids.iu.edu/."
 *
 * Alternatively, this acknowledgement may appear in the software itself, and 
 * wherever such third-party acknowledgments normally appear.
 * 
 *4) The name Indiana University or Community Grids Lab or NaradaBrokering, 
 * shall not be used to endorse or promote products derived from this software 
 * without prior written permission from Indiana University.  For written 
 * permission, please contact the Advanced Research and Technology Institute 
 * ("ARTI") at 351 West 10th Street, Indianapolis, Indiana 46202.
 *5) Products derived from this software may not be called NaradaBrokering, 
 * nor may Indiana University or Community Grids Lab or NaradaBrokering appear
 * in their name, without prior written permission of ARTI.
 * 
 *
 * Indiana University provides no reassurances that the source code provided 
 * does not infringe the patent or any other intellectual property rights of 
 * any other entity.  Indiana University disclaims any liability to any 
 * recipient for claims brought by any other entity based on infringement of 
 * intellectual property rights or otherwise.  
 *
 *LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH NO 
 *WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA UNIVERSITY GIVES
 *NO WARRANTIES AND MAKES NO REPRESENTATION THAT SOFTWARE IS FREE OF 
 *INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR OTHER PROPRIETARY RIGHTS. 
 *INDIANA UNIVERSITY MAKES NO WARRANTIES THAT SOFTWARE IS FREE FROM "BUGS", 
 *"VIRUSES", "TROJAN HORSES", "TRAP DOORS", "WORMS", OR OTHER HARMFUL CODE.  
 *LICENSEE ASSUMES THE ENTIRE RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR 
 *ASSOCIATED MATERIALS, AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION 
 *GENERATED USING SOFTWARE.
 */
package cgl.narada.wsinfra.wsr.storage.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Calendar;

import javax.xml.namespace.QName;

import cgl.narada.wsinfra.wsr.WsrConstants;
import cgl.narada.wsinfra.wsr.impl.WsrUtil;
import cgl.narada.wsinfra.wsr.storage.WsrProtocolStorageOperations;
import cgl.narada.wsinfra.wsr.storage.WsrStorageException;
/**
 * @author Sima Patel
 * $Date: 2005/03/18 20:18:23 $
 * $Revision: 1.3 $ 
 * Description: Handles Protocol Storage Operations which is defined in 
 * interface WsrProtocolStorageOperations
 */

public class WsrProtocolStorageOperationsImpl implements 
                                     WsrProtocolStorageOperations {

    private WsrQueryHandler wsrQueryHandler;
    private WsrUtil wsrUtil;
    private String moduleName = "WsrProtocolStorageOperationsImpl: ";

    public WsrProtocolStorageOperationsImpl() {}

    public WsrProtocolStorageOperationsImpl(Connection connection) {
        wsrQueryHandler = new WsrQueryHandler(connection);
        wsrUtil = WsrUtil.getInstance();
    }

    /** Processes a set of acknowledgements received on a given group.
    This method throws an exception under the following conditions.
    <br> The group specified by groupId is an unknown one.
    <br> One or more of the acknowledgements refer to 
     non-existent sequence numbers.
    <br> Storage related problems */
    public void processAcknowledgementsOnGroup(String groupId,
					       long[] ackSequenceNumbers) 
                throws WsrStorageException{
        int size = ackSequenceNumbers.length;
        for (int i = 0; i < size; i++) {
            processAcknowledgementOnGroup(groupId, ackSequenceNumbers[i]);
        }
    }
    /** Processes an acknowledgement received on a given group for a specific
    sequence number.
    This method throws an exception under the following conditions.
    <br> The group specified by groupId is an unknown one.
    <br> The acknowledgement refers to non-existent sequence number  
    <br> Storage related problems */
    public void processAcknowledgementOnGroup(String groupId,
					      long ackSequenceNumber) 
                throws WsrStorageException{
        String query = null;
        byte messageStatus = getMessageStatus(groupId, ackSequenceNumber);
        if (messageStatus == WsrConstants.MESSAGE_FAULTED) {
            return;
        }
        query = "update wsrstoragewidget set messageStatus = " +
                 WsrConstants.MESSAGE_ACKNOWLEDGED +
                 " where groupId='" + groupId +
                 "' and sequenceNumber=" + ackSequenceNumber;

        int count = wsrQueryHandler.updateQuery(query);
        
        if (count <= 0) {
            throw new WsrStorageException(moduleName +
            " processAcknowledgementOnGroup exception [" + query + "] " +
            "groupId or sequence number does not exist");

        }

    }
   
    /** Processes Fault received on a given group for a specific
    sequence number.
    This method throws an exception under the following conditions.
    <br> The group specified by groupId is an unknown one.
    <br> The fault refers to non-existent sequence number  
    <br> Storage related problems */
    public void processFaultOnGroup(String groupId,
   			            long sequenceNumber, QName fault) 
                throws WsrStorageException{
        String query = null;
        query = "update wsrstoragewidget set messageStatus = " +
                WsrConstants.MESSAGE_FAULTED +
                ", messageFault = '"+ fault.toString()+"'"+
                " where groupId='" + groupId +
                "' and sequenceNumber=" + sequenceNumber;

        int count = wsrQueryHandler.updateQuery(query);
       
        if (count <= 0) {
            throw new WsrStorageException(moduleName +
            " processFaultOnGroup exception [" + query + "] " +
            "groupId or sequence number does not exist");
        }     
    }
    /** Retrieves the list of sequence numbers that have NOT been acknowledged, 
    up until the sequence number specified in <i>upUntilSequenceNumber</i>
    This method throws an exception under the following conditions.
    <br> The group specified by groupId is an unknown one.
    <br> The specified sequence number is a non-existent one. 
    <br> Storage related problems  */
    public long[] getUnacknowledgedSequenceNumbers(String groupId,
  						     long upUntilSequenceNumber)
                  throws WsrStorageException{
        String query = null;
        query = "select count(*) from wsrstoragewidget where groupId='"
                 + groupId + "'";
        if (!wsrQueryHandler.isExistInTable(query)) {
            throw new WsrStorageException(moduleName +
            " getUnacknowledgedSequenceNumbers exception [" + query + "] " +
            "group Id does not exist");
        }
        query =
            "select count(*) from wsrstoragewidget where sequenceNumber="
            + upUntilSequenceNumber;

        if (!wsrQueryHandler.isExistInTable(query)) {
            throw new WsrStorageException(moduleName +
            " getUnacknowledgedSequenceNumbers  exception [" + query + "] " +
            "specified sequence number does not exist");
        }

        query =
            "select sequenceNumber from wsrstoragewidget where groupId='"
            + groupId + "'" + "and messageStatus = 0"+
            " and sequenceNumber <= " + upUntilSequenceNumber;

        PreparedStatement preparedStatement =
                                    wsrQueryHandler.getPreparedStatement(query);
        ResultSet resultSet = wsrQueryHandler.getResultSet(preparedStatement);

        long[] unacknowledgedSequenceNumbers = wsrQueryHandler.getLongNumbers(
                                                                     resultSet);

        wsrQueryHandler.closeResultSet(resultSet);
        wsrQueryHandler.closePreparedStatement(preparedStatement);

        return unacknowledgedSequenceNumbers;

    }
    /** Retrieves the list of sequence numbers that have NOT been acknowledged 
    and not faulted for a given group.This
    method throws an exception if the group specified by 
    <i>groupId</i> is an unknown one or if there are other 
    storage problems. */
    public long[] getUnacknowledgedSequenceNumbers(String groupId)
                  throws WsrStorageException{
      
        String query =
            "select count(*) from wsrstoragewidget where groupId='"
            + groupId + "'";

        if (!wsrQueryHandler.isExistInTable(query)) {
            throw new WsrStorageException(moduleName +
            " getUnacknowledgedSequenceNumbers exception [" + query + "] " +
            "groupId does not exist");
        }
        query =
              "select sequenceNumber from wsrstoragewidget where groupId='" +
              groupId + "' and messageStatus = 0";  

        PreparedStatement preparedStatement =
                                    wsrQueryHandler.getPreparedStatement(query);
        ResultSet resultSet = wsrQueryHandler.getResultSet(preparedStatement);

        long[] unacknowledgedSequenceNumbers = wsrQueryHandler.getLongNumbers(
            resultSet);
        wsrQueryHandler.closeResultSet(resultSet);
        wsrQueryHandler.closePreparedStatement(preparedStatement);
        return unacknowledgedSequenceNumbers;
    }
    /** Retrieves the list of sequence numbers that have NOT been Delivered, 
    and have sequenceNumber greater than specified sequenceNumber
    This method throws an exception under the following conditions.
    <br> The group specified by groupId is an unknown one.
    <br> Storage related problems  */
    public long[] getUnDeliveredSequenceNumbers(String groupId,
						                        long sequenceNumber)
                  throws WsrStorageException{
    	 String query = null;
         query = "select count(*) from wsrstoragewidget where groupId='"
                  + groupId + "'";
         if (!wsrQueryHandler.isExistInTable(query)) {
             throw new WsrStorageException(moduleName +
             " getUnDeliveredSequenceNumbers exception [" + query + "] " +
             "group Id does not exist");
         }
         query =
             "select sequenceNumber from wsrstoragewidget where groupId='"
             + groupId + "'" + "and messageStatus = "+
			 WsrConstants.MESSAGE_NOT_DELIVERED +
             " and sequenceNumber > " + sequenceNumber;

         PreparedStatement preparedStatement =
                                     wsrQueryHandler.getPreparedStatement(query);
         ResultSet resultSet = wsrQueryHandler.getResultSet(preparedStatement);

         long[] undeliveredSequenceNumbers = wsrQueryHandler.getLongNumbers(
                                                                      resultSet);

         wsrQueryHandler.closeResultSet(resultSet);
         wsrQueryHandler.closePreparedStatement(preparedStatement);

         return undeliveredSequenceNumbers;
    	
    }
    
    /** Retrieves the list of sequence numbers that have NOT been Delivered
    for a given group.This
    method throws an exception if the group specified by 
    <i>groupId</i> is an unknown one or if there are other 
    storage problems. */
    public long[] getUnDeliveredSequenceNumbers(String groupId)
                  throws WsrStorageException{
      
        String query =
            "select count(*) from wsrstoragewidget where groupId='"
            + groupId + "'";

        if (!wsrQueryHandler.isExistInTable(query)) {
            throw new WsrStorageException(moduleName +
            "getUnDeliveredSequenceNumbers exception [" + query + "] " +
            "groupId does not exist");
        }
        query =
              "select sequenceNumber from wsrstoragewidget where groupId='" +
              groupId + "' and messageStatus = " +
              WsrConstants.MESSAGE_NOT_DELIVERED ;  

        PreparedStatement preparedStatement =
                                    wsrQueryHandler.getPreparedStatement(query);
        ResultSet resultSet = wsrQueryHandler.getResultSet(preparedStatement);

        long[] undeliveredSequenceNumbers = wsrQueryHandler.getLongNumbers(
            resultSet);
        wsrQueryHandler.closeResultSet(resultSet);
        wsrQueryHandler.closePreparedStatement(preparedStatement);
        return undeliveredSequenceNumbers;
    }


    /** Retrieves the list of sequence numbers that have been acknowledged
    This method throws WsrStorageException.*/
    public long[] getAcknowledgedSequenceNumbers(String groupId) 
                  throws WsrStorageException{

        String query = null;
        query = "select count(*) from wsrstoragewidget where groupId='"
            + groupId + "'";

        if (!wsrQueryHandler.isExistInTable(query)) {
            throw new WsrStorageException(moduleName +
                                     " getAcknowledgedSequenceNumbers exception"
                                     + "[" + query + "] " +
                                     "groupId does not exist");

        }

        query =
            "select sequenceNumber from wsrstoragewidget where groupId='"
            + groupId + "'" + "and messageStatus = "+
                WsrConstants.MESSAGE_ACKNOWLEDGED;

        PreparedStatement preparedStatement =
            wsrQueryHandler.getPreparedStatement(query);
        ResultSet resultSet = wsrQueryHandler.getResultSet(preparedStatement);

        long[] acknowledgedSequenceNumbers =
            wsrQueryHandler.getLongNumbers(resultSet);

        wsrQueryHandler.closeResultSet(resultSet);
        wsrQueryHandler.closePreparedStatement(preparedStatement);

        return acknowledgedSequenceNumbers;

    }
    /** Retrieves the list of all sequence numbers */
    public long[] getSequenceNumbers(String groupId) 
                  throws WsrStorageException{

        String query = null;
        query = "select count(*) from wsrstoragewidget where groupId='"
            + groupId + "'";

        if (!wsrQueryHandler.isExistInTable(query)) {
          throw new WsrStorageException(moduleName +
                                         " getSequenceNumbers exception"
                                         + "[" + query + "] " +
                                         "groupId does not exist");

        }

        query =
            "select sequenceNumber from wsrstoragewidget where groupId='"
            + groupId + "'";

        PreparedStatement preparedStatement =
                                    wsrQueryHandler.getPreparedStatement(query);
        ResultSet resultSet = wsrQueryHandler.getResultSet(preparedStatement);

        long[]sequenceNumbers = wsrQueryHandler.getLongNumbers(resultSet);

        wsrQueryHandler.closeResultSet(resultSet);
        wsrQueryHandler.closePreparedStatement(preparedStatement);

        return sequenceNumbers;

    }

    /** Retrieves the sequence number that was last assigned on a given
    group. This method throws an exception if the group
    specified by groupId is an unknown one or if there are 
    storage related problems.  */
    public long getSequenceNumberLastAssigned(String groupId)
                throws WsrStorageException{

        String query =
            "select max(sequenceNumber) from wsrstoragewidget where groupId='"
            + groupId + "'";
        long sequenceNumber = wsrQueryHandler.getLongNumber(query);
        return sequenceNumber;
    }
    /** Gets the Status of the Message from storage*/
    public byte getMessageStatus(String groupId, long sequenceNumber)
                throws WsrStorageException{
        byte messageStatus =0;
        String query = null;
        query = "select messageStatus from wsrstoragewidget where groupId='"+
                groupId +"'and sequenceNumber="+sequenceNumber;

        PreparedStatement preparedStatement = 
                                   wsrQueryHandler.getPreparedStatement(query);
        ResultSet resultSet = wsrQueryHandler.getResultSet(preparedStatement);

        try {
            while (resultSet.next()) {
                messageStatus = resultSet.getByte(1);
            }
        }catch (SQLException ex) {
            throw new WsrStorageException(moduleName + 
                                          "exception In getMessageStatus["
                                         + query + "] " + ex.toString());
        }
        wsrQueryHandler.closeResultSet(resultSet);
        wsrQueryHandler.closePreparedStatement(preparedStatement); 
        return messageStatus;
    }
  
    /** Gets the Fault associate with the message if message is faulted from 
    storage*/
    public String getMessageFault(String groupId, long sequenceNumber)
                   throws WsrStorageException{
        String messageFault = null;
        String query = null;
        query = "select messageFault from wsrstoragewidget where groupId='"+
            groupId +"'and sequenceNumber="+sequenceNumber;
       
        PreparedStatement preparedStatement = 
                wsrQueryHandler.getPreparedStatement(query);
        ResultSet resultSet = wsrQueryHandler.getResultSet(preparedStatement);

        try {
            while (resultSet.next()) {
                messageFault = resultSet.getString(1);
            }

        }catch (SQLException ex) {
            throw new WsrStorageException(moduleName + 
                                          "exception In getMessageFault["
                                         + query + "] " + ex.toString());
        }
        wsrQueryHandler.closeResultSet(resultSet);
        wsrQueryHandler.closePreparedStatement(preparedStatement); 
        return messageFault;
      
    }
    /** Store a WSR message to storage. This method throws an exception if 
    there are storage related problems. */
    public void store(WsrStorageWidgetImpl widget)
                throws WsrStorageException {

        String groupId = widget.getGroupId();
        
        long sequenceNumber = widget.getSequenceNumber();
        
        Calendar messageExpiryTime = widget.getMessageExpiryTime();
        
        String replyPattern = widget.getReplyPattern();
        
        String replyTo = widget.getReplyTo();
        
        byte messageStatus = widget.getMessageStatus();
        
        QName messageFault = widget.getMessageFault();
        
        byte[] envelopeDocument = widget.getBytesOfEnvelopeDocument(); 
        
        long retransmissionTime = widget.getRetransmissionTime();
        
        byte numberOfRetries = widget.getNumberOfRetries();
        String query = null;
        boolean initialDataCreation = false;
        if(!hasStoredElement(groupId, sequenceNumber)){
            initialDataCreation = true;
        }
        if (initialDataCreation) {
            query =
            "insert into wsrstoragewidget values('" + groupId + "',"
            + sequenceNumber + ",'" + 
            wsrUtil.getStringOfCalendar(messageExpiryTime)+"','"+
            replyPattern +"','"+replyTo+"',"+ messageStatus + ",'"+
            messageFault+"',?,"+
            retransmissionTime +","+numberOfRetries+")";
        }else {
            query = "update wsrstoragewidget set " +
             "messageExpiryTime = '"+ wsrUtil.getStringOfCalendar
                                               (messageExpiryTime)+"',"  +
             "replyPattern = '" + replyPattern +"',"+
             "replyTo = '" + replyTo +"',"+
             "messageStatus = " + messageStatus +","+
             "messageFault = '" + messageFault +"',"+
             "envelopeDocument = ?,"+
             "retransmissionTime = "+retransmissionTime +","+
			 "numberOfRetries = "+numberOfRetries +			 
             " where groupId ='" + groupId + "'"+
             "and sequenceNumber =" + sequenceNumber;
        }
        PreparedStatement pstmt1 = wsrQueryHandler.getPreparedStatement(query);
        try {
            pstmt1.setBytes(1, envelopeDocument);
            pstmt1.executeUpdate();
            pstmt1.close();
        }catch (SQLException ex) {
            throw new WsrStorageException(moduleName + "store exception ["
                                         + query + "] " + ex.toString());
        }
        

    }
    /** Checks to see if there are widgets that have been stored for the
    group in question. */
    public boolean hasStoredElements(String groupId) 
                   throws WsrStorageException {
        boolean boolValue = false;
        if (groupId == null) {
            throw new WsrStorageException(moduleName +
              " hasStoredElements exception groupId is null");

        }
        String query = "select count(*) from wsrstoragewidget where groupId='"
                        + groupId + "'";
        if (wsrQueryHandler.isExistInTable(query)) {
            boolValue = true;
        }
        return boolValue;
    }

    /** Check to see if there is a widget that has been stored for a specific
    sequence number in a given group */
    public boolean hasStoredElement(String groupId, long sequenceNumber) 
                   throws WsrStorageException {

        boolean boolValue = false;
        if (groupId == null) {
            throw new WsrStorageException(moduleName + "hasStoredElement() " +
                                         "exception groupId is null");

        }
        String query =
            "select count(*) from wsrstoragewidget " +
            " where groupId ='" + groupId +
            "' and sequenceNumber =" + sequenceNumber;

        if (wsrQueryHandler.isExistInTable(query)) {
            boolValue = true;
        }
        return boolValue;

    }

    /** Retrieves a stored WsrStorageWidget from storage. This method throws an
    exception under the following conditions.
    <br> The group specified in groupId is an unknown one.
    <br> The specified sequenceNumber is a non-existent one.
    <br> Storage related problems  */
    public WsrStorageWidgetImpl getStoredElement(String groupId,
                                                 long sequenceNumber) 
                                throws WsrStorageException {
        WsrStorageWidgetImpl wsrStorageWidgetImpl = null;
        String query = null;
        query =
            "select * from wsrstoragewidget where groupId='"
            + groupId + "' and sequenceNumber=" + sequenceNumber;

        PreparedStatement preparedStatement =
                                   wsrQueryHandler.getPreparedStatement(query);
        ResultSet resultSet = wsrQueryHandler.getResultSet(preparedStatement);
        try{
            while(resultSet.next()){
                Calendar messageExpiryTime = 
                	wsrUtil.getCalendarOfString(
                                      resultSet.getString("messageExpiryTime"));
                String replyPattern = resultSet.getString("replyPattern");
                String replyTo = resultSet.getString("replyTo");
                byte messageStatus = resultSet.getByte("messageStatus");
                QName messageFault = (QName.valueOf(resultSet.getString
                                                            ("messageFault")));
                byte[] envelopeDocument = resultSet.getBytes("envelopeDocument");
                long retransmissionTime=resultSet.getLong("retransmissionTime");
                byte numberOfRetries = resultSet.getByte("numberOfRetries");
                wsrStorageWidgetImpl = new WsrStorageWidgetImpl(groupId, 
                                           sequenceNumber, messageExpiryTime,
                                           replyPattern, replyTo, 
                                           messageStatus, messageFault,
                                           retransmissionTime,numberOfRetries, 
                                           envelopeDocument);
            }
        }catch(SQLException ex) {
            throw new WsrStorageException(moduleName +
                                         " getStored Element exception "
                                         + ex.toString());


        }
        wsrQueryHandler.closeResultSet(resultSet);
        wsrQueryHandler.closePreparedStatement(preparedStatement);
        return wsrStorageWidgetImpl;
    }

    /** Retrieves stored WsrStorageWidgets from storage. This method throws an
    exception under the following conditions.
    <br> The group specified by groupId is an unknown one.
    <br> One or more of the specified sequence numbers are non-existent. 
    <br> Storage related problems */
    public WsrStorageWidgetImpl[] getStoredElements(String groupId,
		                                    long[]sequenceNumbers) 
                                  throws WsrStorageException {
        int size = sequenceNumbers.length;
        WsrStorageWidgetImpl[] wsrStorageWidget =
                                                new WsrStorageWidgetImpl[size];
        for (int i = 0; i < size; i++) {
            wsrStorageWidget[i] = getStoredElement(groupId,
                                                  sequenceNumbers[i]);
        }
        return wsrStorageWidget;
    }
    /** Removes stored WsrStorageWidget from storage. This method throws an
    exception under the following conditions.
    <br> The group specified by groupId is an unknown one.
    <br> Storage related problems */
    public void deleteStoredElement(String groupId, long sequenceNumber) 
                throws WsrStorageException{
        String query = "delete from wsrstoragewidget where groupId='"
        + groupId + "' and sequenceNumber=" + sequenceNumber;
        int row = wsrQueryHandler.updateQuery(query);
        
      
    }
    /** Stores the GroupTerminationInfo object.
    This method stores the groupTerminationInfo object in storage
    If groupId in groupTerminationInfo object is already exist
    then it updates the GroupTerminationInfo Object in storage. 
    This method throws exception if 
    <br> Storage related problems 
    */
    public void storeGroupTerminationInfo(
                               WsrGroupTerminationInfoImpl groupTerminationInfo)
                throws WsrStorageException{
        String groupId = groupTerminationInfo.getGroupId();
        boolean isGroupComplete = groupTerminationInfo.isGroupComplete();
        boolean isGroupClosed = groupTerminationInfo.isGroupClosed();
        boolean isGroupRemoved = groupTerminationInfo.isGroupRemoved();
        boolean isGroupExpiryTimePassed = 
                                 groupTerminationInfo.isGroupExpiryTimePassed();
        boolean isGroupMaxIdleDurationPassed = 
                           groupTerminationInfo.isGroupMaxIdleDurationPassed();
        boolean isMessageExpired = groupTerminationInfo.isMessageExpired();
        boolean isMessageFaulted = groupTerminationInfo.isMessageFaulted();
        boolean hasLastMessageOfGroup = groupTerminationInfo.
        hasLastMessageOfGroup();
        boolean hasMaxSequenceNumber = groupTerminationInfo.
        hasMaxSequenceNumber();
        boolean isSource = groupTerminationInfo.isSource();

        String query = 
                "select count(*) from wsrgroupterminationinfo where groupId='"
                + groupId + "'";
        boolean initialDataCreation = false;
        if (wsrQueryHandler.getLongNumber(query) <= 0) {
            initialDataCreation = true;
        }
        if (initialDataCreation) {
            query =
            "insert into wsrgroupterminationinfo values('" + groupId + "',"
            + wsrQueryHandler.getIntOfBoolean(isGroupComplete)+","+
            wsrQueryHandler.getIntOfBoolean(isGroupClosed)+","+
            wsrQueryHandler.getIntOfBoolean(isGroupRemoved)+","+
            wsrQueryHandler.getIntOfBoolean(isGroupExpiryTimePassed)+","+
            wsrQueryHandler.getIntOfBoolean(isGroupMaxIdleDurationPassed)+","+
            wsrQueryHandler.getIntOfBoolean(hasLastMessageOfGroup)+","+
            wsrQueryHandler.getIntOfBoolean(hasMaxSequenceNumber)+","+
            wsrQueryHandler.getIntOfBoolean(isMessageExpired)+","+
            wsrQueryHandler.getIntOfBoolean(isMessageFaulted)+","+
			wsrQueryHandler.getIntOfBoolean(isSource)+")";
        }else {
            query = "update wsrgroupterminationinfo  set " +
            "isGroupComplete = " + 
                             wsrQueryHandler.getIntOfBoolean(isGroupComplete) +
            ",isGroupClosed = " + 
                             wsrQueryHandler.getIntOfBoolean(isGroupClosed) +
            ",isGroupRemoved = " + 
                             wsrQueryHandler.getIntOfBoolean(isGroupRemoved) +
            ",isGroupExpiryTimePassed = " + 
                     wsrQueryHandler.getIntOfBoolean(isGroupExpiryTimePassed) +
            ",isGroupMaxIdleDurationPassed = " + 
                 wsrQueryHandler.getIntOfBoolean(isGroupMaxIdleDurationPassed) +
            ",hasLastMessageOfGroup = " +
                       wsrQueryHandler.getIntOfBoolean(hasLastMessageOfGroup) +
            ",hasMaxSequenceNumber = " + 
                    wsrQueryHandler.getIntOfBoolean(hasMaxSequenceNumber) +
            ",isMessageExpired = " + 
                    wsrQueryHandler.getIntOfBoolean(isMessageExpired) +
            ",isMessageFaulted = " + 
                    wsrQueryHandler.getIntOfBoolean(isMessageFaulted) +
            " where groupId='" + groupId + "'";;
        }
        PreparedStatement pstmt1 = wsrQueryHandler.getPreparedStatement(query);
        try {
            pstmt1.executeUpdate();
            pstmt1.close();
        }catch (SQLException ex) {
            throw new WsrStorageException(moduleName +
                            "storeGroupTerminationInfo exception ["
                             + query + "] " + ex.toString());
        }
       
    }
    /** Retrieves the GroupTerminationInfo object.
    This method retrieves the groupTerminationInfo object for 
    particular groupId from storage
    This method throws an exception under the
    following circumstances
    <br> The groupId in the GroupTerminationInfo not exists.
    <br> Storage related problems 
    */
    public WsrGroupTerminationInfoImpl getGroupTerminationInfo(String groupId)
                                       throws WsrStorageException{
        WsrGroupTerminationInfoImpl wsrGroupTerminationInfoImpl=null;
        String query =
            "select * from wsrgroupterminationinfo where groupId='"
            + groupId + "'";
        PreparedStatement preparedStatement =
                                    wsrQueryHandler.getPreparedStatement(query);
        ResultSet resultSet = wsrQueryHandler.getResultSet(preparedStatement);
        try{
            while(resultSet.next()){
                boolean isGroupComplete = 
                        resultSet.getBoolean("isGroupComplete");
                boolean isGroupClosed = resultSet.getBoolean("isGroupClosed");
                boolean isGroupRemoved = resultSet.getBoolean("isGroupRemoved");
                boolean isGroupExpiryTimePassed = 
                        resultSet.getBoolean("isGroupExpiryTimePassed");
                boolean isGroupMaxIdleDurationPassed = 
                        resultSet.getBoolean("isGroupMaxIdleDurationPassed");
                boolean isMessageExpired = 
                        resultSet.getBoolean("isMessageExpired");
                boolean isMessageFaulted = 
                        resultSet.getBoolean("isMessageFaulted");
                boolean hasLastMessageOfGroup = 
                        resultSet.getBoolean("hasLastMessageOfGroup");
                boolean hasMaxSequenceNumber = 
                        resultSet.getBoolean("hasMaxSequenceNumber");
                boolean isSource = resultSet.getBoolean("isSource");
                wsrGroupTerminationInfoImpl = new WsrGroupTerminationInfoImpl
                (groupId,isGroupComplete, isGroupClosed, isGroupRemoved, 
                isGroupExpiryTimePassed, isGroupMaxIdleDurationPassed, 
                hasLastMessageOfGroup, hasMaxSequenceNumber, 
                isMessageExpired, isMessageFaulted,isSource);
            }

        }catch(SQLException se){
            se.printStackTrace();
            throw new WsrStorageException(moduleName + 
                    "getGroupInfoUsingGroupId exception ["
                                     + "] " + se.toString());
        }
        wsrQueryHandler.closeResultSet(resultSet);
        wsrQueryHandler.closePreparedStatement(preparedStatement);
        return  wsrGroupTerminationInfoImpl;
    }
    /** Delete the GroupTerminationInfo object.
    This method deletes the groupTerminationInfo object for particular 
    groupId from storage
    This method throws an exception under the
    following circumstances
    <br> The groupId in the GroupTerminationInfo not exists.
    <br> Storage related problems 
    */
    public void deleteGroupTerminationInfo(String groupId)
                throws WsrStorageException{
        String query = "delete from wsrgroupterminationinfo where groupId='"
                          + groupId+"'";
        int row = wsrQueryHandler.updateQuery(query);
        
    }
    /** Reset the Retranmission Time associated with the message */
    public void resetRetransmissionTime(WsrStorageWidgetImpl wsrStorageWidgetImpl,
			                long retransmissionTime)
                throws WsrStorageException{
        String groupId = wsrStorageWidgetImpl.getGroupId();
        long sequenceNumber = wsrStorageWidgetImpl.getSequenceNumber();
        String query =
                      "update wsrstoragewidget set retransmissionTime=" 
                       + retransmissionTime +
                       " where groupId ='" + groupId 
                       + "' and sequenceNumber =" +
                       sequenceNumber;

        PreparedStatement pstmt1 = wsrQueryHandler.getPreparedStatement(query);
        try {
            pstmt1.executeUpdate();
            pstmt1.close();
        }catch (SQLException ex) {
            throw new WsrStorageException(moduleName +
                                    "resetRetransmissionTime exception ["
                                     + query + "] " + ex.toString());
        }  
    }
    /** Reset the Number Of Retries associated with the 
     * retransmission of the message*/
    public void resetNumberOfRetries(WsrStorageWidgetImpl wsrStorageWidgetImpl,
    		                         byte numberOfRetries)
                throws WsrStorageException{
    	String groupId = wsrStorageWidgetImpl.getGroupId();
        long sequenceNumber = wsrStorageWidgetImpl.getSequenceNumber();
        String query =
                      "update wsrstoragewidget set numberOfRetries=" 
                       + numberOfRetries +
                       " where groupId ='" + groupId 
                       + "' and sequenceNumber =" +
                       sequenceNumber;

        PreparedStatement pstmt1 = wsrQueryHandler.getPreparedStatement(query);
        try {
            pstmt1.executeUpdate();
            pstmt1.close();
        }catch (SQLException ex) {
            throw new WsrStorageException(moduleName +
                                    "resetNumberOfRetries exception ["
                                     + query + "] " + ex.toString());
        }  
    	
    }
    public static void main(String[] args) {
        WsrProtocolStorageOperationsImpl wsrProtocolStorageOperationsImpl = new
                                             WsrProtocolStorageOperationsImpl();

    }
}